home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
asxsrc.arc
/
ASOUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-10
|
7KB
|
441 lines
/* asout.c */
/*
* (C) Copyright 1989
* All Rights Reserved
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*/
#include <stdio.h>
#include <setjmp.h>
#include "asm.h"
#define R_WORD 0 /* 16 bit */
#define R_BYTE 01
#define R_AREA 0 /* Base type */
#define R_SYM 02
#define R_NORM 0 /* PC adjust */
#define R_PCR 04
#define R_DEF 00 /* Global def. */
#define R_REF 01 /* Global ref. */
#define R_REL 00 /* Relocatable */
#define R_ABS 02 /* Absolute */
#define R_GBL 00 /* Global */
#define R_LCL 04 /* Local */
#define NTXT 16
#define NREL 16
char txt[NTXT];
char rel[NREL];
char *txtp = { &txt[0] };
char *relp = { &rel[0] };
/*
* Output absolute byte.
*/
VOID
outab(b)
{
if (pass == 2) {
out_lb(b);
if (oflag) {
outchk(1, 0);
*txtp++ = lobyte(b);
}
}
++dot->s_addr;
}
/*
* Output absolute word.
* Low then high.
*/
VOID
outaw(w)
{
if (pass == 2) {
out_lw(w);
if (oflag) {
outchk(2, 0);
out_tw(w);
}
}
dot->s_addr += 2;
}
/*
* Output relocatable byte.
*/
VOID
outrb(esp, pcrf)
register struct expr *esp;
{
register n, r;
if (pass == 2) {
out_lb(esp->e_addr);
if (oflag) {
if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
outchk(1, 0);
*txtp++ = lobyte(esp->e_addr);
} else {
outchk(1, 4);
*txtp++ = lobyte(esp->e_addr);
r = R_BYTE;
if (pcrf)
r |= R_PCR;
if (esp->e_flag) {
n = esp->e_base.e_sp->s_ref;
r |= R_SYM;
} else {
n = esp->e_base.e_ap->a_ref;
}
*relp++ = r;
*relp++ = txtp - txt - 1;
out_rw(n);
}
}
}
++dot->s_addr;
}
/*
* Output relocatable word.
* Low then high.
*/
VOID
outrw(esp, pcrf)
register struct expr *esp;
{
register n, r;
if (pass == 2) {
out_lw(esp->e_addr);
if (oflag) {
if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
outchk(2, 0);
out_tw(esp->e_addr);
} else {
outchk(2, 4);
out_tw(esp->e_addr);
r = R_WORD;
if (pcrf)
r |= R_PCR;
if (esp->e_flag) {
n = esp->e_base.e_sp->s_ref;
r |= R_SYM;
} else {
n = esp->e_base.e_ap->a_ref;
}
*relp++ = r;
*relp++ = txtp - txt - 2;
out_rw(n);
}
}
}
dot->s_addr += 2;
}
/*
* Clear out any bufferred text and relocation information
*/
VOID
outall()
{
if (oflag && pass==2)
outbuf();
}
/*
* Check text buffer and relocation buffer.
*/
VOID
outchk(nt, nr)
{
register struct area *ap;
if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
outbuf();
}
if (txtp == txt) {
out_tw(dot->s_addr);
if (ap = dot->s_area) {
*relp++ = R_WORD|R_AREA;
*relp++ = 0;
out_rw(ap->a_ref);
}
}
}
/*
* Output any bufferred text and relocation information
*/
VOID
outbuf()
{
if (txtp > &txt[2]) {
fprintf(ofp, "T");
out(txt, txtp-txt);
fprintf(ofp, "\n");
txtp = txt;
if (relp > rel) {
fprintf(ofp, "R");
out(rel, relp-rel);
fprintf(ofp, "\n");
relp = rel;
}
} else {
txtp = txt;
relp = rel;
}
}
/*
* Walk through the symbol table and the
* area list and put out the global
* symbol information at the front of the
* relocatable file. This routine is also
* responsible for setting up the reference
* numbers in the symbol tabel.
*/
VOID
outgsd()
{
register struct area *ap;
register struct sym *sp;
register i, j;
char *ptr;
int c, narea, nglob, rn;
narea = areap->a_ref + 1;
nglob = 0;
for (i = 0; i < NHASH; ++i) {
sp = symhash[i];
while (sp) {
if (sp->s_flag&S_GBL)
++nglob;
sp = sp->s_sp;
}
}
if (xflag == 0) {
fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
} else
if (xflag == 1) {
fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
} else
if (xflag == 2) {
fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
}
/*
* Module name
*/
if (module[0]) {
fprintf(ofp, "M ");
ptr = &module[0];
while (ptr < &module[NCPS]) {
if (c = *ptr++)
putc(c, ofp);
}
putc('\n', ofp);
}
/*
* Global references and absolutes.
*/
rn = 0;
for (i=0; i<NHASH; ++i) {
sp = symhash[i];
while (sp) {
if (sp->s_area==NULL && sp->s_flag&S_GBL) {
sp->s_ref = rn++;
outsym(sp);
}
sp = sp->s_sp;
}
}
/*
* Global relocatables.
*/
for (i=0; i<narea; ++i) {
ap = areap;
while (ap->a_ref != i)
ap = ap->a_ap;
outarea(ap);
for (j=0; j<NHASH; ++j) {
sp = symhash[j];
while (sp) {
if (sp->s_area==ap && sp->s_flag&S_GBL) {
sp->s_ref = rn++;
outsym(sp);
}
sp = sp->s_sp;
}
}
}
}
/*
* Output the relocatable item defining
* an area.
*/
VOID
outarea(ap)
register struct area *ap;
{
register char *ptr;
register c;
fprintf(ofp, "A ");
ptr = &ap->a_id[0];
while (ptr < &ap->a_id[NCPS]) {
if (c = *ptr++)
putc(c, ofp);
}
if (xflag == 0) {
fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
} else
if (xflag == 1) {
fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
} else
if (xflag == 2) {
fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
}
}
/*
* Output the relocatable item describing a
* global symbol.
*/
VOID
outsym(sp)
register struct sym *sp;
{
register char *ptr;
register c;
fprintf(ofp, "S ");
ptr = &sp->s_id[0];
while (ptr < &sp->s_id[NCPS]) {
if (c = *ptr++)
putc(c, ofp);
}
fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
if (xflag == 0) {
fprintf(ofp, "%04X\n", sp->s_addr);
} else
if (xflag == 1) {
fprintf(ofp, "%06o\n", sp->s_addr);
} else
if (xflag == 2) {
fprintf(ofp, "%05u\n", sp->s_addr);
}
}
VOID
out(p, n)
register char *p;
register n;
{
while (n--) {
if (xflag == 0) {
fprintf(ofp, " %02X", (*p++)&0377);
} else
if (xflag == 1) {
fprintf(ofp, " %03o", (*p++)&0377);
} else
if (xflag == 2) {
fprintf(ofp, " %03u", (*p++)&0377);
}
}
}
/*
* Output a byte to the listing buffer.
*/
VOID
out_lb(b)
register b;
{
if (cp < &cb[NCODE])
*cp++ = b;
}
/*
* Output ordered word to the listing buffer.
*/
VOID
out_lw(n)
register n;
{
if (hilo) {
out_lb(hibyte(n));
out_lb(lobyte(n));
} else {
out_lb(lobyte(n));
out_lb(hibyte(n));
}
}
/*
* Output ordered 'Relocation' word.
*/
VOID
out_rw(n)
register n;
{
if (hilo) {
*relp++ = hibyte(n);
*relp++ = lobyte(n);
} else {
*relp++ = lobyte(n);
*relp++ = hibyte(n);
}
}
/*
* Output ordered 'Text' word.
*/
VOID
out_tw(n)
register n;
{
if (hilo) {
*txtp++ = hibyte(n);
*txtp++ = lobyte(n);
} else {
*txtp++ = lobyte(n);
*txtp++ = hibyte(n);
}
}
/*
* Extract low half of a word.
*/
int
lobyte(n)
{
return (n&0377);
}
/*
* Extract high half of a word.
*/
int
hibyte(n)
{
return ((n>>8)&0377);
}